package com.fengycx.mq.listener;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fengycx.constants.Constants;
import com.fengycx.pojo.domain.Order;
import com.fengycx.service.IOrderService;
import com.fengycx.utils.AssertUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
@Slf4j
@RocketMQTransactionListener(txProducerGroup = "order-to-pay-group")
public class OrderToPayListener implements RocketMQLocalTransactionListener {

    @Autowired
    private IOrderService orderService;

    /**
     * 执行本地事务的地方
     * @param msg  消费者执行事务需要的数据（这里不需要做处理，直接提交事务即可）
     * @param arg  本地事务执行需要的数据
     * @return
     */
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        try {
            Order order = JSONUtil.toBean(JSONUtil.toJsonStr(arg), Order.class);
            orderService.updateById(order);
            return RocketMQLocalTransactionState.COMMIT;
        } catch (Exception e) {
            log.error("执行本地事务消息失败，错误消息：{}"+e.getMessage());
            return RocketMQLocalTransactionState.ROLLBACK;
        }
    }

    /**
     * 回查 本地事务是否执行成功，上面的方法如果一分钟还没响应，则会调用该方法进行回查
     * 根据上面方法的业务逻辑是否执行成功来判断，这里就是查询order更新成功没有，成功就是commit，失败就是rollback
     * @param msg 消费者消费的消息
     * @return
     */
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
        JSONObject jsonObject = JSONUtil.parseObj(msg.getPayload());
        String orderNo = jsonObject.getStr("orderNo");
        Order order = orderService.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNo, orderNo));
        AssertUtil.isNotNull(order,"事务消息发送失败，请联系管理员");

        try {
            if(!Constants.Order.UNPAID.equals(order.getStatus())){
              return  RocketMQLocalTransactionState.ROLLBACK;
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("执行本地事务失败，错误消息：{}" +e.getMessage());
        }
        return  RocketMQLocalTransactionState.COMMIT;
    }
}
